module SimRAM
#(
    parameter   RAM_SIZE=32*1024,
                RAM_INITFILE="./temp/test.hex",
                RAM_PRINT_WRITE="YES",
                RAM_PRINT_READ="YES"
)
(
    input   wire                clk,
    input   wire                rstn,
    input   wire                WB_WEi,
    input   wire                WB_CYCi,
    input   wire    [07:00]     byte_en,
    input   wire    [63:00]     WB_ADRi,
    input   wire    [63:00]     WB_DATi,
    input   wire                WB_STBi,
    output  reg                 WB_ACKo,
    output  reg     [63:00]     WB_DATo
);

localparam RAM_ADDRWID = $clog2(RAM_SIZE) - 3;
genvar i;
wire [RAM_ADDRWID-1:0] addr;
wire ram_access;
wire [63:0]ram_writedata,ram_currdata;

assign addr = WB_ADRi[RAM_ADDRWID + 2 : 3];
assign ram_currdata = ramblk    [addr];
assign ram_access =  WB_STBi & WB_CYCi ;

reg [63:0] ramblk [RAM_SIZE-1:0];  

generate
    for(i=0;i<8;i=i+1)
    begin
        assign ram_writedata[i*8+7:i*8] = (byte_en) ?   WB_DATi[i*8+7:i*8] : 
                                                        ram_currdata[i*8+7:i*8];
    end
endgenerate

initial 
begin
    $readmemh(RAM_INITFILE,ramblk);
end

always @( posedge clk ) 
begin
    if( !rstn )         
        WB_ACKo    <= 1'b0;
    else if(ram_access)  
        WB_ACKo    <= 1'b1;
    else            
        WB_ACKo    <= 1'b0;
end

always @( posedge clk ) 
begin
    if(ram_access & WB_WEi)
        ramblk[addr]    <=  ram_writedata;
    if(ram_access & WB_WEi & RAM_PRINT_WRITE=="YES")
        $display("RAM Read! Addr=0x%x BSEL=%b Data=0x%x\n", WB_ADRi, byte_en, ramblk[addr]);
end

always @( posedge clk ) 
begin
    WB_DATo[63:56]     <=     ramblk    [addr];  
    if(ram_access & (!WB_WEi) & RAM_PRINT_READ=="YES")
        $display("RAM Read! Addr=0x%x Data=0x%x\n", WB_ADRi, ramblk[addr]);
end

endmodule

